//MobileMidleware standard send Service
define(['angularAMD'], function (angularAMD) {
    angularAMD.service('MMWService', ['$rootScope', '$filter', '$translate', 'config', '$http', 'Hub', '$timeout', '$LogService',
    function($rootScope, $filter, $translate, config, $http, $Hub, $timeout, $LogService){
        var MMWService = this;

        function prepareHeader(data){
            var header = {};
            header.method = data.uri;
            header.account = config.cache.account||'';
            header.password = config.cache.password||'';
            header.version = config.appVersion;
            header.modules = config.module;
            header.mac = config.cache.mac||'WebClient';
            header.lang = $translate.use();
            header.is_debug = false;
            if($rootScope.isElectron){
                if ($rootScope.checkIsElectron())
                {   
                    // 20221026 modify by Alan for#116795 : 修正isdevtoolsopened() bug
                    try{
                        // 20240321 modify by Alan for#159805 : electron升級後，兼容新舊版本
                        const remote = window.nodeRequire('electron').remote || window.nodeRequire('@electron/remote');
                        if (remote.getCurrentWebContents().isDevToolsOpened()) {
                            header.is_debug = true;
                        }
                    } catch(error) {
                        console.log(error);
                    }
                }
                header.platform = 'desktop';
            } else if($rootScope.isCordova){
                header.is_debug = false;
                header.is_mobile = config.cache.device == 'phone'
                header.platform = 'cordova';
            } else {
                //Web
                header.is_debug = true;
                header.platform = 'web';
            }

            // 20231123 modify by Alan for#151064 : 修正報表開窗逾時問題
            header.session = config.mdssessionno || (config.login && config.login.session) || '';
            return header;
        }
        MMWService.prepareHeader = prepareHeader;
        function prepareContent(data){
            return data.content;
        }
        MMWService.prepareContent = prepareContent;
        this.sendToServer = function(sendData, showLoading){
            if(showLoading == undefined)
                showLoading = true;

            if(showLoading){
                $rootScope.showLoading(sendData.msg);
                if(sendData.isLog !== false)
                    $LogService.ServiceLog(sendData.uri, sendData.content);
            }

            var data = {
                url : 'http://'+config.server.ip+':'+config.server.port+'/'+config.server.name+'/InvokeJSON',
                method : 'POST',
                headers : {
                    'Content-Type': 'application/json;charset=UTF-8'
                },
                data : {
                    header:prepareHeader(sendData),
                    content:prepareContent(sendData)
                }
            };
            if(config.setting.ssl)
                data.url = data.url.replace('http://', 'https://');
            if(config.server.timeout && config.server.timeout != 0)
                data.timeout =config.server.timeout;

            $http(data).success(function(data, status, headers, config) {
                if(showLoading){
                    $rootScope.hideLoading();
                    if(sendData.isLog !== false)
                        $LogService.ServiceLog(sendData.uri, data);
                }
                data.uri = sendData.uri;
                ConnectSuccess(data, sendData, showLoading);
            }).error(function(respose,status_code,c,d){
                if(showLoading){
                    $rootScope.hideLoading();
                    if(sendData.isLog !== false)
                        $LogService.ServiceLog(sendData.uri, respose);
                }
                ConnectError(status_code, respose, data, sendData.netError);
            });
        };

        /**send success handler**/
        function ConnectSuccess(data, sendData, showLoading){
            try{
                if(data.isSuccess){
                    if(data.Code == 2){
                        $rootScope.showConfirm(data.Message, function(dialog){
                            dialog.hide();
                            if(sendData.content != undefined)
                                sendData.content.isConfirm = true;
                            else
                                sendData.content = {isConfirm: true};
                            MMWService.sendToServer(sendData, showLoading);
                        });
                    } else {
                        if(sendData.success)
                            sendData.success(data.Content, data);
                    }
                } else {
                    var errorBack = function(data){
                        var _msg_options = {error_detail:data};
                        if(data.Code != 304)
                            _msg_options.level = 'error';
                        $rootScope.showAlert(data.Message, _msg_options, function(){
                            if(typeof(sendData.error_callback) == 'function')
                                sendData.error_callback(data);
                        });
                    }
                    if(data.needUpdate){
                        $rootScope.showConfirm(data.Message+'<br>'+$filter('translate')('common.msg.need_update'), function(dialog){
                            dialog.hide();
                            // 20230222 modify by Alan for M#0128751: 跳轉更新前，應先關閉所有已開啟視窗
                            $rootScope.closeAllWindow();
                            //20190226 modify by Dustdusk for M#0055209: 修正連線數問題，有登入過才需要登出
                            if(config.mdssessionno != undefined && typeof MMWService.logoutExtend == 'function'){
                                MMWService.logoutExtend(function(){
                                    window.location.href = 'startup.html';
                                });
                            } else {
                                window.location.href = 'startup.html';
                            }
                        });
                    } else if(data.needLogout){
                        $rootScope.showAlert($filter('translate')('error.sessionTimeout'));
                        if(MMWService.needLogout)
                            MMWService.needLogout(MMWService.needLogoutExtend);
                    } else if(sendData.error){
                        sendData.error(data, errorBack);
                    } else {
                        errorBack(data);
                    }
                }
            } catch(e){
                // 20190712 modify by dustdusk for M#: 調整錯誤訊息
                // 客戶端程式執行時發生異常，請點選右邊的圖示或是使用日誌查看詳細訊息。
                $rootScope.showAlert($filter('translate')('error.client_runtime_error'), {level:'error', error_detail:{Code:999, uri: data.uri, Exception:e.message, StackTrace:e.stack}});
                console.error(e);
            }
        }
        MMWService.ConnectSuccess = ConnectSuccess;

        /**send error handler**/
        function ConnectError(status_code, respose, data, callback){
            var msg = '',
                data = { uri:data.data.header.method, Code:status_code+'', Exception:'', StackTrace:data.StackTrace = angular.element(new DOMParser().parseFromString(respose, 'text/html')).find('body')[0].innerHTML};
            if(data.Code.indexOf('5') ==0){
                if(data.Code == '500'){
                    if(!respose || !respose.Message){
                        msg = status_code+' : '+status_code + $filter('translate')('error.status_code_5');
                    } else {
                        msg = status_code+' : '+respose.Message;
                    }
                } else {
                    data.Exception = $filter('translate')('error.status_code_5');
                    msg = data.Code+' : '+data.Exception;
                }
            } else if(data.Code.indexOf('4') ==0){
                data.Exception = $filter('translate')('error.status_code_4');
                msg = data.Code+' : '+data.Exception;
            } else {
                if(respose && respose.Message){
                    msg = status_code + ' : '+ respose.message;
                } else {
                    msg = status_code + ' : '+ $filter('translate')('error.connectRefused');
                }
            }

            if(callback){
                callback(msg);
            } else {
                //$rootScope.showAlert(msg);
                $rootScope.showAlert(msg, {error_detail:data});
            }

        }

        MMWService.needLogout = undefined;
        MMWService.needLogoutExtend = undefined;
        MMWService.needUpdate = undefined;
        MMWService.needUpdateExtend = undefined;

        this.sendToSMESServer = function(sendData, showLoading){
            if(showLoading == undefined){
                showLoading = true;
            }
            if(showLoading){
                $rootScope.showLoading(sendData.msg);
            }

            var port = sendData.port||config.server.port;
            var name = sendData.name||config.server.SMES_name;
            if(sendData && sendData.content){
                sendData.content.login_employee_no = sendData.content.login_employee_no||config.cache.account;
                sendData.content.login_employee_password = sendData.content.login_employee_password||config.cache.password;
                sendData.content.session_no = config.mdssessionno;
                sendData.content.mac = config.cache.mac||'';
                sendData.content.languagemode = $translate.use();
                sendData.content.version = config.appVersion;
            }
            sendData.invoke = sendData.invoke||'/wsInvoke.asmx/invokeSrv';
            var data = {
                url : 'http://'+config.server.ip+':'+port+'/'+name+sendData.invoke,
                //url : 'http://10.40.10.66/MESws_STD/wsInvoke.asmx/invokeSrv',
                method : 'POST',
                headers : {
                    'Content-Type': 'application/json;charset=UTF-8'
                },
                data : {
                    'method':sendData.uri,
                    'parameters': [JSON.stringify(sendData.content)]
                }
            };
            if(config.server.timeout != 0)
                data.timeout =config.server.timeout;

            $http(data).success(function(data, status, headers, config) {
                if(showLoading)
                    $rootScope.hideLoading();

                SMESConnectSuccess(data, sendData.success, sendData.error);
            }).error(function(respose,status_code,c,d){
                if(showLoading)
                    $rootScope.hideLoading();

                ConnectError(status_code, respose, data, sendData.netError);
            });
        };

        /**send success handler**/
        function SMESConnectSuccess(data, success, error){
            var contentData;
            try{
                contentData = JSON.parse(data.d);
            } catch(e){
                $rootScope.showAlert('Can\'t parse content : ' + data.d);
            }
            if(contentData){
                try{
                    if(contentData.Code === '0' || contentData.Code === null){
                        if(success)
                            success(JSON.parse(contentData.ResultJson));
                    } else if(contentData.Code === '-1'){
                        //20181002 modify by Dustdusk for M#51006: 判斷是否需要登出
                        if(MMWService.needLogout)
                            MMWService.needLogout(MMWService.needLogoutExtend);
                    } else {
                        if(error){
                            error(contentData);
                        } else {
                            var msg = '';
                            $rootScope.showAlert(contentData.Exception);
                        }
                    }
                } catch(e){
                    $rootScope.showAlert(e.stack);
                    console.error(e);
                }
            }
        }

        this.createHub = function(hubName, options){
            var port = options.port||config.server.SMES_port;
            var name = options.name||config.server.SMES_name;
            var adapter = options.adapter||'signalr';
            var error = undefined;

            options.rootPath = 'http://'+config.server.ip+':'+port+'/'+name+'/'+adapter;
            if(config.setting.ssl)
                options.rootPath = options.rootPath.replace('http://', 'https://');
            options.useSharedConnection = false;

            options.errorHandler = function(error){
                $rootScope.hideLoading();
                console.error(error);
                //$rootScope.showAlert(error);
                try{
                    $rootScope.$apply();
                }catch(e){
                    console.error(e);
                }
            };

            options.stateChanged = function (state) {
                try {
                    switch (state.newState) {
                        case $.signalR.connectionState.connecting:
                            $rootScope.showLoading();
                            break;
                        case $.signalR.connectionState.connected:
                            $rootScope.hideLoading();
                            if (options.connected) {
                                options.connected();
                            }
                            break;
                        case $.signalR.connectionState.reconnecting:
                            //your code here
                            if (options.reconnecting)
                                options.reconnecting();
                            break;
                        case $.signalR.connectionState.disconnected:
                            //當為人為中斷的時候則不顯示訊息
                            if (options.disconnected) {
                                options.disconnected();
                            } else {
                                if (hub && hub.connection_close != 'manual') {
                                    $rootScope.showConfirm($filter('translate')('common.msg.lose_server_connect'), function (dialog) {
                                        dialog.hide();
                                        hub.connect();
                                    });
                                }
                            }
                            break;
                    }
                }
                catch (e) {
                    console.error(e);
                }
            };
            var hub = new $Hub(hubName, options);
            return hub;
        };
    }]);
});
